package com.jsh.erp.ding;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkcontact_1_0.models.SearchDepartmentHeaders;
import com.aliyun.dingtalkcontact_1_0.models.SearchDepartmentRequest;
import com.aliyun.dingtalkcontact_1_0.models.SearchDepartmentResponse;
import com.aliyun.dingtalkoauth2_1_0.Client;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceHeaders;
import com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest;
import com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.OpenApiRequest;
import com.aliyun.teaopenapi.models.Params;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsh.erp.datasource.entities.*;
import com.jsh.erp.datasource.mappers.UserMapper;
import com.jsh.erp.service.material.MaterialService;
import com.jsh.erp.service.tenant.TenantService;
import com.jsh.erp.utils.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 项目采购申请流程code :
 */
@Service
public class DingService {
    @Autowired
    private DingConfiguration dingConfiguration;
    @Resource private UserMapper userMapper;
    @Resource private MaterialService materialService;
    private Logger logger = LoggerFactory.getLogger(DingService.class);
    private String accessToken = null;

    public String getAccessToken(){
//        if (StringUtils.isNotEmpty(accessToken) ){
//            return accessToken;
//        }else{
            Client client = null;
            try {
                com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
                config.protocol = "https";
                config.regionId = "central";
                client = new com.aliyun.dingtalkoauth2_1_0.Client(config);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest();
            getAccessTokenRequest.setAppKey(dingConfiguration.getAppKey());
            getAccessTokenRequest.setAppSecret(dingConfiguration.getAppSecret());
            try {
                GetAccessTokenResponse getAccessTokenResponse = client.getAccessToken(getAccessTokenRequest);
                if ( getAccessTokenResponse.statusCode == 200) {
                    accessToken = getAccessTokenResponse.getBody().getAccessToken();
                    return accessToken;
                }
            } catch (TeaException err) {
                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                    // err 中含有 code 和 message 属性，可帮助开发定位问题
                }

            } catch (Exception _err) {
                TeaException err = new TeaException(_err.getMessage(), _err);
                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                    // err 中含有 code 和 message 属性，可帮助开发定位问题
                }

            }
//        }
        return null ;
    }

    /**
     * 采购申请审批
     */
    public StartProcessInstanceResponse startPurchaseApplyProcessInstance(List<DepotItemVo4WithInfoEx> detailList,String projectName,
                                                                          String customerName, String applyDesc,
                                                                          String purchaseTotal, String depotHeadNumber, String createDingUserid){
        applyDesc = (applyDesc ==null)?"无":applyDesc;

        List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> valuesList = Lists.newArrayList();
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("项目名称").setValue(projectName));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("客户名称").setValue(customerName));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("申请备注").setValue(applyDesc));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("采购总金额").setValue(purchaseTotal));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("申请单号").setValue(depotHeadNumber));

        JSONArray detailArray = new JSONArray();
        detailArray.add(new JSONObject().fluentPut("name","名称").fluentPut("value","1"));
        detailArray.add(new JSONObject().fluentPut("name","制造商").fluentPut("value","2"));

        JSONArray detailResultArray = new JSONArray();
        detailResultArray.add(detailArray);


        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("材料明细").setComponentType("TableField").setValue(detailResultArray.toJSONString()));

        StartProcessInstanceResponse response = this.sendDingRequest(dingConfiguration.getProcCodePurchaseApply(),createDingUserid, valuesList);
        return response;
    }

    /**
     * 采购订单审批
     */
    public StartProcessInstanceResponse startPurchaseOrderProcessInstance(List<DepotItemVo4WithInfoEx> detailList, DepotHead depotHead, Project project, Contract contract, Supplier supplier, String createDingUserid) throws Exception {
        String applyDesc = (depotHead.getRemark() ==null)?"无":depotHead.getRemark();
        String projectName = (project == null )?"无":project.getName();
        List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> valuesList = Lists.newArrayList();
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("项目名称").setValue(projectName));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("采购订单单据号").setValue(depotHead.getNumber()));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("采购总金额").setValue(String.valueOf(depotHead.getTotalPrice().multiply(new BigDecimal(-1)))));
        if ( contract != null ){
            valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("合同编号").setValue(contract.getSn()));
            valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("合同名称").setValue(contract.getName()));
        }else{
            valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("合同编号").setValue("无"));
            valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("合同名称").setValue("无"));
        }

        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("供应商").setValue(supplier.getSupplier()));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("备注").setValue(applyDesc));

        JSONArray details = new JSONArray();
        for (DepotItemVo4WithInfoEx detail : detailList){
            JSONArray detailItem = new JSONArray();
            Material material = materialService.getMaterial(detail.getMaterialId().longValue());

            detailItem.add(new JSONObject().fluentPut("name","名称").fluentPut("value",detail.getMName()));
            detailItem.add(new JSONObject().fluentPut("name","型号").fluentPut("value",detail.getMModel()));
            detailItem.add(new JSONObject().fluentPut("name","制造商").fluentPut("value",detail.getMMfrs()));
            detailItem.add(new JSONObject().fluentPut("name","尺寸").fluentPut("value",material.getOtherField1()));
            detailItem.add(new JSONObject().fluentPut("name","温度").fluentPut("value",material.getOtherField2()));
            detailItem.add(new JSONObject().fluentPut("name","压力").fluentPut("value",material.getOtherField3()));
            detailItem.add(new JSONObject().fluentPut("name","材质").fluentPut("value",material.getCaizhi()));
            detailItem.add(new JSONObject().fluentPut("name","标准").fluentPut("value",material.getBiaozhun()));
            detailItem.add(new JSONObject().fluentPut("name","长度").fluentPut("value",material.getChangdu()));
            detailItem.add(new JSONObject().fluentPut("name","抛光度").fluentPut("value",material.getPaoguangdu()));
            detailItem.add(new JSONObject().fluentPut("name","连接").fluentPut("value",material.getLianjie()));
            detailItem.add(new JSONObject().fluentPut("name","密封").fluentPut("value",material.getMopian()));
            detailItem.add(new JSONObject().fluentPut("name","单位").fluentPut("value",detail.getUnitName()));
            detailItem.add(new JSONObject().fluentPut("name","数量").fluentPut("value",detail.getOperNumber()));
            details.add(detailItem);
        }

        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("材料明细").setComponentType("TableField").setValue(details.toJSONString()));


        StartProcessInstanceResponse response = this.sendDingRequest(dingConfiguration.getProcCodePurchaseOrder(),createDingUserid, valuesList);
        return response;
    }


    /**
     * 领料订单审批
     */
    public StartProcessInstanceResponse startLingLiaoOrderProcessInstance(List<DepotItemVo4WithInfoEx> detailList, DepotHead depotHead, Project project,String createDingUserid) throws Exception {
        String applyDesc = (depotHead.getRemark() ==null)?"无":depotHead.getRemark();
        String projectName = (project == null )?"无":project.getName();
        List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> valuesList = Lists.newArrayList();
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("项目名称").setValue(projectName));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("领料单据号").setValue(depotHead.getNumber()));
        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("备注").setValue(applyDesc));

        JSONArray details = new JSONArray();
        for (DepotItemVo4WithInfoEx detail : detailList){
            JSONArray detailItem = new JSONArray();
            Material material = materialService.getMaterial(detail.getMaterialId().longValue());

            detailItem.add(new JSONObject().fluentPut("name","名称").fluentPut("value",detail.getMName()));
            detailItem.add(new JSONObject().fluentPut("name","型号").fluentPut("value",detail.getMModel()));
            detailItem.add(new JSONObject().fluentPut("name","制造商").fluentPut("value",detail.getMMfrs()));
            detailItem.add(new JSONObject().fluentPut("name","尺寸").fluentPut("value",material.getOtherField1()));
            detailItem.add(new JSONObject().fluentPut("name","温度").fluentPut("value",material.getOtherField2()));
            detailItem.add(new JSONObject().fluentPut("name","压力").fluentPut("value",material.getOtherField3()));
            detailItem.add(new JSONObject().fluentPut("name","材质").fluentPut("value",material.getCaizhi()));
            detailItem.add(new JSONObject().fluentPut("name","标准").fluentPut("value",material.getBiaozhun()));
            detailItem.add(new JSONObject().fluentPut("name","长度").fluentPut("value",material.getChangdu()));
            detailItem.add(new JSONObject().fluentPut("name","抛光度").fluentPut("value",material.getPaoguangdu()));
            detailItem.add(new JSONObject().fluentPut("name","连接").fluentPut("value",material.getLianjie()));
            detailItem.add(new JSONObject().fluentPut("name","密封").fluentPut("value",material.getMopian()));
            detailItem.add(new JSONObject().fluentPut("name","单位").fluentPut("value",detail.getUnitName()));
            detailItem.add(new JSONObject().fluentPut("name","数量").fluentPut("value",detail.getOperNumber()));
            details.add(detailItem);
        }

        valuesList.add(new StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues().setName("材料明细").setComponentType("TableField").setValue(details.toJSONString()));

        StartProcessInstanceResponse response = this.sendDingRequest(dingConfiguration.getProcCodeLingLiao(),createDingUserid, valuesList);

        return response;
    }

    public JSONArray getDepartmentList(){
        String accessToken = getAccessToken();
        String deptUrl = "https://oapi.dingtalk.com/topapi/v2/department/listsub?access_token="+accessToken;
        Map<String,Object> deptParams = Maps.newHashMap();
        String deptResult = HttpUtil.post(deptUrl, deptParams);
        JSONArray deptList = JSONObject.parseObject(deptResult).getJSONArray("result");

        String userUrl = "https://oapi.dingtalk.com/topapi/v2/user/list?access_token="+accessToken;
        JSONArray allUserList = new JSONArray();
        for (int i = 0; i < deptList.size(); i++) {
            Long deptId = deptList.getJSONObject(i).getLong("dept_id");
            Map<String,Object> userParams = Maps.newHashMap();
            userParams.put("dept_id", deptId);
            userParams.put("cursor", 0);
            userParams.put("size", 100);
            String userResult = HttpUtil.post(userUrl, userParams);
            JSONArray userList = JSONObject.parseObject(userResult).getJSONObject("result").getJSONArray("list");
            allUserList.addAll(userList);
        }

        List<User> users = userMapper.selectByExample(new UserExample());
        for (User user : users){
            String ddUserId = "-1";
            for (int i = 0; i < allUserList.size(); i++) {
                if ( allUserList.getJSONObject(i).getString("name").equals(user.getUsername())){
                    ddUserId = allUserList.getJSONObject(i).getString("userid");
                    break;
                }
            }
            user.setWeixinOpenId(ddUserId);
            userMapper.updateByPrimaryKey(user);
        }


        return allUserList;
    }

    private StartProcessInstanceResponse sendDingRequest(String processCode,String originatorUserId,List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> valuesList ){
        StartProcessInstanceHeaders startProcessInstanceHeaders = new StartProcessInstanceHeaders();
        startProcessInstanceHeaders.xAcsDingtalkAccessToken = getAccessToken();

        StartProcessInstanceRequest startProcessInstanceRequest = new StartProcessInstanceRequest()
                .setDeptId(-1L)
                .setOriginatorUserId(originatorUserId)
                .setProcessCode(processCode)
                .setFormComponentValues(valuesList);
        try {
            StartProcessInstanceResponse processInstanceResponse = getClient()
                    .startProcessInstanceWithOptions(startProcessInstanceRequest, startProcessInstanceHeaders, new RuntimeOptions());
            return processInstanceResponse;
        } catch (TeaException err) {
            System.out.println(err.message);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        }

        return null ;
    }

    private com.aliyun.dingtalkworkflow_1_0.Client getClient(){
        com.aliyun.dingtalkworkflow_1_0.Client client = null;
        try {
            com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
            config.protocol = "https";
            config.regionId = "central";
            client = new com.aliyun.dingtalkworkflow_1_0.Client(config);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return client;
    }
}
